#include "qt_knx.h"
#include "knx_interface.h"
#include "cmei.h"
#include <QStringList>
#include <QTime>
#include <QJsonDocument>
#include <QJsonObject>


void print_data(_string *title,void *src,_int32 len)
{
    _u8 *data = (_u8 *)src;
    _int32 n = 1;
    printf("\nDebug MEM: %s \n",title);
    while (n<=len) {
        printf(" %02x",*data);
        if(n%8 == 0)
            printf("\n");
        data++;
        n++;
    }
    printf("\n");
}

/*处理事件
**
**execMsecs :本函数需要被执行的毫秒数，本函数最少会被执行execMsecs毫秒
**maxtime :允许处理事件的最长毫秒数
**flags :允许处理的事件类型
**
**注意：该函数主要用于延时，同时不释放锁，不阻碍调用线程中的其他事件的执行
**  本函数使用QCoreApplication::processEvents实现，建议execMsecs>=maxtime
*/
void processEvents(int execMsecs,int maxtime,QEventLoop::ProcessEventsFlags flags)
{
    QTime dieTime=QTime::currentTime().addMSecs(execMsecs);
    while(QTime::currentTime()<dieTime){
        /*如果在maxtime时间段内没有事件可被执行，
        **  则QCoreApplication::processEvents返回
        **否则QCoreApplication::processEvents执行最长maxtime毫秒
        */
        QCoreApplication::processEvents(flags,maxtime);
    }
}

QByteArray DEVICE_OBJECT::getKnxBytesFromQString(QString value,DATA_TYPE data_type,DATA_DEFINE value_define)
{
    char tmpBuf[16] = {0};
    int data_len = 0;
    if((data_len = DEVICE_OBJECT::KnxQStringToData(value,data_type,value_define,(_u8 *)tmpBuf)) == -1)
    {
        qDebug() << "getKnxBytesFromQString: error data args !";
    }

    QByteArray devData(tmpBuf,data_len);

    return devData;
}

int DEVICE_OBJECT::KnxQStringToData(QString value, DATA_TYPE data_type, DATA_DEFINE value_define, _u8 *buffer)
{
    switch (data_type) {
        case    ONE_BIT_VALUE:
        case    TWO_BIT_VALUE:
        case    THREE_BIT_VALUE:
        case    FOUR_BIT_VALUE:
        case    FIVE_BIT_VALUE:
        case    SIX_BIT_VALUE:
        case    SEVEN_BIT_VALUE:
        {
            unsigned int bit = value.toUInt();
            buffer[0] = 0x1&bit ;
            return 1;
        }
        case ONE_BYTE_VALUE:
        {
            if (value_define == SIGNED_INT) {
                char byte = (char)value.toInt();
                memccpy(buffer, &byte, 1, 1);
            }
            else
            {
                _u8 byte = (_u8)value.toUInt();
                memccpy(buffer, &byte, 1, 1);
            }

            return 1;
        }
        case TWO_BYTES_VALUE:
        {

            if (value_define == SIGNED_INT) {
                short byte = (short)value.toInt();
                short_2bytes((_u8 *)&byte,buffer);
            }
            else if(value_define == UNSIGNED_INT)
            {
                _u16 byte = (_u16)value.toUInt();
                short_2bytes((_u8 *)&byte,buffer);
            }
            else
            {
                float fvalue = value.toFloat();
                degree_2bytes((int)fvalue,buffer);
            }

            return 2;
        }
        case THREE_BYTES_VALUE:
        {
            if (value_define == THREE_BYTES_TIME) {
                QStringList arrysValue = value.split(":");

                KNX_VALUE_TIME ktime;
                memset(&ktime,0, sizeof(KNX_VALUE_TIME));

                if(arrysValue.count() >0)
                    ktime.dayOfWeek = arrysValue.at(0).toUInt() ;

                if(arrysValue.count()>1)
                    ktime.hour = arrysValue.at(1).toUInt() ;

                if(arrysValue.count()>2)
                    ktime.min = arrysValue.at(2).toUInt() ;

                if(arrysValue.count()>3)
                    ktime.second = arrysValue.at(3).toUInt() ;

                time_2_bytes3(buffer,&ktime);

            }
            else
            {
                KNX_VALUE_DATE kdate;
                memset(&kdate,0, sizeof(KNX_VALUE_DATE));
                QStringList arrysValue = value.split("-");

                if(arrysValue.count()>0)
                    kdate.years = arrysValue.at(0).toUInt() ;

                if(arrysValue.count()>1)
                    kdate.month = arrysValue.at(1).toUInt() ;

                if(arrysValue.count()>2)
                    kdate.dayOfMonth = arrysValue.at(2).toUInt() ;

                date_2_bytes3(buffer,&kdate);
            }

            return 3;
        }
        case FOUR_BYTES_VALUE:
        {
            if (value_define == SIGNED_INT) {
                int iValue = value.toInt();
                int_4bytes((_u8 *)&iValue, buffer);
            }
            else
            {
                _u32 uValue = (_u32)value.toUInt();
                int_4bytes((_u8 *)&uValue, buffer);
            }
            return 4;
        }

        default:
        {
            printf("knxDataExchange : Not support this data type not...%d \n",data_type);
            return -1;
        }
    }

}

QString DEVICE_OBJECT::KnxDataToQString(DATA_TYPE data_type,DATA_DEFINE value_define, _u8 * buffer,int size)
{
    QString retString;

    switch (data_type) {
        case    ONE_BIT_VALUE:
        case    TWO_BIT_VALUE:
        case    THREE_BIT_VALUE:
        case    FOUR_BIT_VALUE:
        case    FIVE_BIT_VALUE:
        case    SIX_BIT_VALUE:
        case    SEVEN_BIT_VALUE:
        {
            retString = (buffer[0] & 0x1) == 0x0 ? "0":"1" ;
            break;
        }
        case ONE_BYTE_VALUE:
        {
            if (value_define == SIGNED_INT) {
                retString = QString("%1").arg((char)buffer[0]);
            }
            else if(value_define == UNSIGNED_INT)
            {
                retString =  QString("%1").arg((unsigned char)buffer[0]);
            }
            else
            {
                _u32 tmpValue = ((unsigned char)buffer[0]) & 0xFF;
                retString = QString("%1").arg(tmpValue*100/0xff);
            }
            break;
        }
        case TWO_BYTES_VALUE:
        {
            if (value_define == SIGNED_INT) {
                short byte = 0;
                bytes2_short(NULL, &byte, buffer);

                retString = QString("%1").arg(byte);
            }
            else if(value_define == UNSIGNED_INT)
            {
                unsigned short byte = 0;
                bytes2_short(&byte,NULL,buffer);
                retString = QString("%1").arg(byte);
            }
            else
            {
                float fvalue = 0;
                bytes_2_degree(buffer, &fvalue);
                retString = QString("%1").arg((long)fvalue);
            }

            break;
        }
        case THREE_BYTES_VALUE:
        {
            break;
        }
        case FOUR_BYTES_VALUE:
        {
            if (value_define == SIGNED_INT) {
                int iValue = 0;
                bytes4_int(NULL, &iValue, buffer);
                retString = QString("%1").arg(iValue);
            }
            else if(value_define == UNSIGNED_INT)
            {
                unsigned int uValue = 0;
                bytes4_int(&uValue, NULL, buffer);
                retString = QString("%1").arg(uValue);
            }
            else
            {
                float uValue = 0;
                bytes4_float((_u8 *)&uValue, buffer);
                retString = QString("%1").arg(uValue);
            }

            break ;
        }

        default:
        {
            printf("knxDataExchange : Not support this data type not...%d \n",data_type);
            break;
        }
    }

    return retString;
}
